1   /*                        __    __  __  __    __  ___
2    *                       \  \  /  /    \  \  /  /  __/
3    *                        \  \/  /  /\  \  \/  /  /
4    *                         \____/__/  \__\____/__/.ɪᴏ
5    * ᶜᵒᵖʸʳᶦᵍʰᵗ ᵇʸ ᵛᵃᵛʳ ⁻ ˡᶦᶜᵉⁿˢᵉᵈ ᵘⁿᵈᵉʳ ᵗʰᵉ ᵃᵖᵃᶜʰᵉ ˡᶦᶜᵉⁿˢᵉ ᵛᵉʳˢᶦᵒⁿ ᵗʷᵒ ᵈᵒᵗ ᶻᵉʳᵒ
6    */
7   package io.vavr.collection;
8   
9   import io.vavr.Tuple;
10  import io.vavr.Value;
11  import io.vavr.Tuple2;
12  import org.assertj.core.api.*;
13  import org.junit.Test;
14  
15  import java.math.BigDecimal;
16  import java.util.ArrayList;
17  import java.util.Spliterator;
18  import java.util.function.Function;
19  import java.util.function.Supplier;
20  import java.util.stream.Collector;
21  
22  import static org.junit.Assert.assertTrue;
23  
24  public class HashSetTest extends AbstractSetTest {
25  
26      @Override
27      protected <T> IterableAssert<T> assertThat(Iterable<T> actual) {
28          return new IterableAssert<T>(actual) {
29              @Override
30              public IterableAssert<T> isEqualTo(Object obj) {
31                  @SuppressWarnings("unchecked")
32                  final Iterable<T> expected = (Iterable<T>) obj;
33                  final java.util.Map<T, Integer> actualMap = countMap(actual);
34                  final java.util.Map<T, Integer> expectedMap = countMap(expected);
35                  assertThat(actualMap.size()).isEqualTo(expectedMap.size());
36                  actualMap.keySet().forEach(k -> assertThat(actualMap.get(k)).isEqualTo(expectedMap.get(k)));
37                  return this;
38              }
39  
40              private java.util.Map<T, Integer> countMap(Iterable<? extends T> it) {
41                  final java.util.HashMap<T, Integer> cnt = new java.util.HashMap<>();
42                  it.forEach(i -> cnt.merge(i, 1, (v1, v2) -> v1 + v2));
43                  return cnt;
44              }
45          };
46      }
47  
48      @Override
49      protected <T> ObjectAssert<T> assertThat(T actual) {
50          return new ObjectAssert<T>(actual) {
51          };
52      }
53  
54      @Override
55      protected BooleanAssert assertThat(Boolean actual) {
56          return new BooleanAssert(actual) {
57          };
58      }
59  
60      @Override
61      protected DoubleAssert assertThat(Double actual) {
62          return new DoubleAssert(actual) {
63          };
64      }
65  
66      @Override
67      protected IntegerAssert assertThat(Integer actual) {
68          return new IntegerAssert(actual) {
69          };
70      }
71  
72      @Override
73      protected LongAssert assertThat(Long actual) {
74          return new LongAssert(actual) {
75          };
76      }
77  
78      @Override
79      protected StringAssert assertThat(String actual) {
80          return new StringAssert(actual) {
81          };
82      }
83  
84      // -- construction
85  
86      @Override
87      protected <T> Collector<T, ArrayList<T>, HashSet<T>> collector() {
88          return HashSet.collector();
89      }
90  
91      @Override
92      protected <T> HashSet<T> empty() {
93          return HashSet.empty();
94      }
95  
96      @Override
97      protected <T> HashSet<T> emptyWithNull() {
98          return empty();
99      }
100 
101     @Override
102     protected <T> HashSet<T> of(T element) {
103         return HashSet.of(element);
104     }
105 
106     @SuppressWarnings("varargs")
107     @SafeVarargs
108     @Override
109     protected final <T> HashSet<T> of(T... elements) {
110         return HashSet.of(elements);
111     }
112 
113     @Override
114     protected <T> HashSet<T> ofAll(Iterable<? extends T> elements) {
115         return HashSet.ofAll(elements);
116     }
117 
118     @Override
119     protected <T extends Comparable<? super T>> HashSet<T> ofJavaStream(java.util.stream.Stream<? extends T> javaStream) {
120         return HashSet.ofAll(javaStream);
121     }
122 
123     @Override
124     protected HashSet<Boolean> ofAll(boolean... elements) {
125         return HashSet.ofAll(elements);
126     }
127 
128     @Override
129     protected HashSet<Byte> ofAll(byte... elements) {
130         return HashSet.ofAll(elements);
131     }
132 
133     @Override
134     protected HashSet<Character> ofAll(char... elements) {
135         return HashSet.ofAll(elements);
136     }
137 
138     @Override
139     protected HashSet<Double> ofAll(double... elements) {
140         return HashSet.ofAll(elements);
141     }
142 
143     @Override
144     protected HashSet<Float> ofAll(float... elements) {
145         return HashSet.ofAll(elements);
146     }
147 
148     @Override
149     protected HashSet<Integer> ofAll(int... elements) {
150         return HashSet.ofAll(elements);
151     }
152 
153     @Override
154     protected HashSet<Long> ofAll(long... elements) {
155         return HashSet.ofAll(elements);
156     }
157 
158     @Override
159     protected HashSet<Short> ofAll(short... elements) {
160         return HashSet.ofAll(elements);
161     }
162 
163     @Override
164     protected <T> HashSet<T> tabulate(int n, Function<? super Integer, ? extends T> f) {
165         return HashSet.tabulate(n, f);
166     }
167 
168     @Override
169     protected <T> HashSet<T> fill(int n, Supplier<? extends T> s) {
170         return HashSet.fill(n, s);
171     }
172 
173     @Override
174     protected int getPeekNonNilPerformingAnAction() {
175         return 1;
176     }
177 
178     // -- static narrow
179 
180     @Test
181     public void shouldNarrowHashSet() {
182         final HashSet<Double> doubles = of(1.0d);
183         final HashSet<Number> numbers = HashSet.narrow(doubles);
184         final int actual = numbers.add(new BigDecimal("2.0")).sum().intValue();
185         assertThat(actual).isEqualTo(3);
186     }
187 
188     // -- slideBy is not expected to work for larger subsequences, due to unspecified iteration order
189     @Test
190     public void shouldSlideNonNilBySomeClassifier() {
191         // ignore
192     }
193 
194     // TODO move to traversable
195     // -- zip
196 
197     @Test
198     public void shouldZipNils() {
199         final HashSet<Tuple2<Object, Object>> actual = empty().zip(empty());
200         assertThat(actual).isEqualTo(empty());
201     }
202 
203     @Test
204     public void shouldZipEmptyAndNonNil() {
205         final HashSet<Tuple2<Object, Integer>> actual = empty().zip(of(1));
206         assertThat(actual).isEqualTo(empty());
207     }
208 
209     @Test
210     public void shouldZipNonEmptyAndNil() {
211         final HashSet<Tuple2<Integer, Integer>> actual = of(1).zip(empty());
212         assertThat(actual).isEqualTo(empty());
213     }
214 
215     @Test
216     public void shouldZipNonNilsIfThisIsSmaller() {
217         final HashSet<Tuple2<Integer, String>> actual = of(1, 2).zip(of("a", "b", "c"));
218         final HashSet<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"));
219         assertThat(actual).isEqualTo(expected);
220     }
221 
222     @Test
223     public void shouldZipNonNilsIfThatIsSmaller() {
224         final HashSet<Tuple2<Integer, String>> actual = of(1, 2, 3).zip(of("a", "b"));
225         final HashSet<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"));
226         assertThat(actual).isEqualTo(expected);
227     }
228 
229     @Test
230     public void shouldZipNonNilsOfSameSize() {
231         final HashSet<Tuple2<Integer, String>> actual = of(1, 2, 3).zip(of("a", "b", "c"));
232         final HashSet<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"), Tuple.of(3, "c"));
233         assertThat(actual).isEqualTo(expected);
234     }
235 
236     @Test(expected = NullPointerException.class)
237     public void shouldThrowIfZipWithThatIsNull() {
238         empty().zip(null);
239     }
240 
241     // TODO move to traversable
242     // -- zipAll
243 
244     @Test
245     public void shouldZipAllNils() {
246         // ignore
247     }
248 
249     @Test
250     public void shouldZipAllEmptyAndNonNil() {
251         // ignore
252     }
253 
254     @Test
255     public void shouldZipAllNonEmptyAndNil() {
256         final HashSet<?> actual = of(1).zipAll(empty(), null, null);
257         final HashSet<Tuple2<Integer, Object>> expected = of(Tuple.of(1, null));
258         assertThat(actual).isEqualTo(expected);
259     }
260 
261     @Test
262     public void shouldZipAllNonNilsIfThisIsSmaller() {
263         final HashSet<Tuple2<Integer, String>> actual = of(1, 2).zipAll(of("a", "b", "c"), 9, "z");
264         final HashSet<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"), Tuple.of(9, "c"));
265         assertThat(actual).isEqualTo(expected);
266     }
267 
268     @Test
269     public void shouldZipAllNonNilsIfThatIsSmaller() {
270         final HashSet<Tuple2<Integer, String>> actual = of(1, 2, 3).zipAll(of("a", "b"), 9, "z");
271         final HashSet<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"), Tuple.of(3, "z"));
272         assertThat(actual).isEqualTo(expected);
273     }
274 
275     @Test
276     public void shouldZipAllNonNilsOfSameSize() {
277         final HashSet<Tuple2<Integer, String>> actual = of(1, 2, 3).zipAll(of("a", "b", "c"), 9, "z");
278         final HashSet<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"), Tuple.of(3, "c"));
279         assertThat(actual).isEqualTo(expected);
280     }
281 
282     @Test(expected = NullPointerException.class)
283     public void shouldThrowIfZipAllWithThatIsNull() {
284         empty().zipAll(null, null, null);
285     }
286 
287     // TODO move to traversable
288     // -- zipWithIndex
289 
290     @Test
291     public void shouldZipNilWithIndex() {
292         assertThat(this.<String> empty().zipWithIndex()).isEqualTo(this.<Tuple2<String, Integer>> empty());
293     }
294 
295     @Test
296     public void shouldZipNonNilWithIndex() {
297         final HashSet<Tuple2<String, Integer>> actual = of("a", "b", "c").zipWithIndex();
298         final HashSet<Tuple2<String, Integer>> expected = of(Tuple.of("a", 0), Tuple.of("b", 1), Tuple.of("c", 2));
299         assertThat(actual).isEqualTo(expected);
300     }
301 
302     // -- transform()
303 
304     @Test
305     public void shouldTransform() {
306         final String transformed = of(42).transform(v -> String.valueOf(v.get()));
307         assertThat(transformed).isEqualTo("42");
308     }
309 
310     // HashSet special cases
311 
312     @Override
313     public void shouldDropRightAsExpectedIfCountIsLessThanSize() {
314         assertThat(of(1, 2, 3).dropRight(2)).isEqualTo(of(3));
315     }
316 
317     @Override
318     public void shouldTakeRightAsExpectedIfCountIsLessThanSize() {
319         assertThat(of(1, 2, 3).takeRight(2)).isEqualTo(of(1, 2));
320     }
321 
322     @Override
323     public void shouldGetInitOfNonNil() {
324         assertThat(of(1, 2, 3).init()).isEqualTo(of(2, 3));
325     }
326 
327     @Override
328     public void shouldFoldRightNonNil() {
329         final String actual = of('a', 'b', 'c').foldRight("", (x, xs) -> x + xs);
330         final List<String> expected = List.of('a', 'b', 'c').permutations().map(List::mkString);
331         assertThat(actual).isIn(expected);
332     }
333 
334     @Override
335     public void shouldReduceRightNonNil() {
336         final String actual = of("a", "b", "c").reduceRight((x, xs) -> x + xs);
337         final List<String> expected = List.of("a", "b", "c").permutations().map(List::mkString);
338         assertThat(actual).isIn(expected);
339     }
340 
341     @Override
342     public void shouldMkStringWithDelimiterNonNil() {
343         final String actual = of('a', 'b', 'c').mkString(",");
344         final List<String> expected = List.of('a', 'b', 'c').permutations().map(l -> l.mkString(","));
345         assertThat(actual).isIn(expected);
346     }
347 
348     @Override
349     public void shouldMkStringWithDelimiterAndPrefixAndSuffixNonNil() {
350         final String actual = of('a', 'b', 'c').mkString("[", ",", "]");
351         final List<String> expected = List.of('a', 'b', 'c').permutations().map(l -> l.mkString("[", ",", "]"));
352         assertThat(actual).isIn(expected);
353     }
354 
355     @Override
356     public void shouldComputeDistinctByOfNonEmptyTraversableUsingComparator() {
357         // TODO
358     }
359 
360     @Override
361     public void shouldComputeDistinctByOfNonEmptyTraversableUsingKeyExtractor() {
362         // TODO
363     }
364 
365     @Override
366     public void shouldFindLastOfNonNil() {
367         final int actual = of(1, 2, 3, 4).findLast(i -> i % 2 == 0).get();
368         assertThat(actual).isIn(List.of(1, 2, 3, 4));
369     }
370 
371     @Override
372     public void shouldThrowWhenFoldRightNullOperator() {
373         throw new NullPointerException(); // TODO
374     }
375 
376     @Override
377     public void shouldReturnSomeInitWhenCallingInitOptionOnNonNil() {
378         // TODO
379     }
380 
381     @Test
382     public void shouldBeEqual() {
383         assertTrue(HashSet.of(1).equals(HashSet.of(1)));
384     }
385 
386     @Override
387     protected boolean useIsEqualToInsteadOfIsSameAs() {
388         return false;
389     }
390 
391     @Override
392     protected HashSet<Character> range(char from, char toExclusive) {
393         return HashSet.range(from, toExclusive);
394     }
395 
396     @Override
397     protected HashSet<Character> rangeBy(char from, char toExclusive, int step) {
398         return HashSet.rangeBy(from, toExclusive, step);
399     }
400 
401     @Override
402     protected HashSet<Double> rangeBy(double from, double toExclusive, double step) {
403         return HashSet.rangeBy(from, toExclusive, step);
404     }
405 
406     @Override
407     protected HashSet<Integer> range(int from, int toExclusive) {
408         return HashSet.range(from, toExclusive);
409     }
410 
411     @Override
412     protected HashSet<Integer> rangeBy(int from, int toExclusive, int step) {
413         return HashSet.rangeBy(from, toExclusive, step);
414     }
415 
416     @Override
417     protected HashSet<Long> range(long from, long toExclusive) {
418         return HashSet.range(from, toExclusive);
419     }
420 
421     @Override
422     protected HashSet<Long> rangeBy(long from, long toExclusive, long step) {
423         return HashSet.rangeBy(from, toExclusive, step);
424     }
425 
426     @Override
427     protected HashSet<Character> rangeClosed(char from, char toInclusive) {
428         return HashSet.rangeClosed(from, toInclusive);
429     }
430 
431     @Override
432     protected HashSet<Character> rangeClosedBy(char from, char toInclusive, int step) {
433         return HashSet.rangeClosedBy(from, toInclusive, step);
434     }
435 
436     @Override
437     protected HashSet<Double> rangeClosedBy(double from, double toInclusive, double step) {
438         return HashSet.rangeClosedBy(from, toInclusive, step);
439     }
440 
441     @Override
442     protected HashSet<Integer> rangeClosed(int from, int toInclusive) {
443         return HashSet.rangeClosed(from, toInclusive);
444     }
445 
446     @Override
447     protected HashSet<Integer> rangeClosedBy(int from, int toInclusive, int step) {
448         return HashSet.rangeClosedBy(from, toInclusive, step);
449     }
450 
451     @Override
452     protected HashSet<Long> rangeClosed(long from, long toInclusive) {
453         return HashSet.rangeClosed(from, toInclusive);
454     }
455 
456     @Override
457     protected HashSet<Long> rangeClosedBy(long from, long toInclusive, long step) {
458         return HashSet.rangeClosedBy(from, toInclusive, step);
459     }
460 
461     // -- toSet
462 
463     @Test
464     public void shouldReturnSelfOnConvertToSet() {
465         final Value<Integer> value = of(1, 2, 3);
466         assertThat(value.toSet()).isSameAs(value);
467     }
468 
469     // -- spliterator
470 
471     @Test
472     public void shouldNotHaveSortedSpliterator() {
473         assertThat(of(1, 2, 3).spliterator().hasCharacteristics(Spliterator.SORTED)).isFalse();
474     }
475 
476     @Test
477     public void shouldNotHaveOrderedSpliterator() {
478         assertThat(of(1, 2, 3).spliterator().hasCharacteristics(Spliterator.ORDERED)).isFalse();
479     }
480 
481     // -- isSequential()
482 
483     @Test
484     public void shouldReturnFalseWhenIsSequentialCalled() {
485         assertThat(of(1, 2, 3).isSequential()).isFalse();
486     }
487 
488 }